package com.smartlifev30.baiwei.view.expandableList;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;

import java.util.HashMap;
import java.util.List;


/**
 * @param <GVH>           Group View Holder类型
 * @param <GroupDataType> Group 数据类型
 * @param <CVH>           Child View Holder类型
 * @param <ChildDataType> Child 数据类型
 * @author tys
 * @date 2018/9/6
 */
public abstract class BaseExpandableListAdapter<GVH extends BaseExpandableListAdapter.GroupViewHolder, GroupDataType,
        CVH extends BaseExpandableListAdapter.ChildViewHolder, ChildDataType> extends android.widget.BaseExpandableListAdapter {

    protected List<GroupDataType> mGroupData;
    protected HashMap<GroupDataType, List<ChildDataType>> mChildData;
    private Context mContext;

    public BaseExpandableListAdapter(Context context, List<GroupDataType> group, HashMap<GroupDataType, List<ChildDataType>> child) {
        this.mContext = context;
        this.mGroupData = group;
        this.mChildData = child;
    }

    @Override
    public int getGroupCount() {
        return mGroupData.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        GroupDataType g = mGroupData.get(groupPosition);
        return mChildData.get(g).size();
    }

    @Override
    public GroupDataType getGroup(int groupPosition) {
        return mGroupData.get(groupPosition);
    }

    @Override
    public ChildDataType getChild(int groupPosition, int childPosition) {
        GroupDataType g = mGroupData.get(groupPosition);
        return mChildData.get(g).get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GVH holder;
        if (convertView != null) {
            holder = (GVH) convertView.getTag();
        } else {
            holder = onCreateGroupViewHolder(parent, getGroupType(groupPosition));
        }
        onBindGroupViewHolder(holder, groupPosition, isExpanded);
        return holder.groupItemView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        CVH holder;
        if (convertView != null) {
            holder = (CVH) convertView.getTag();
        } else {
            holder = onCreateChildViewHolder(parent, getChildType(groupPosition, childPosition));
        }
        onBindChildViewHolder(holder, groupPosition, childPosition, isLastChild);
        return holder.childItemView;
    }

    /**
     * mGroupData view holder
     *
     * @param parent
     * @param viewType {@link android.widget.BaseExpandableListAdapter#getGroupType(int)}
     * @return
     */
    @NonNull
    protected abstract GVH onCreateGroupViewHolder(ViewGroup parent, int viewType);

    /**
     * mGroupData holder中view的数据
     *
     * @param holder
     * @param groupPosition
     * @param isExpanded
     */
    protected abstract void onBindGroupViewHolder(GVH holder, int groupPosition, boolean isExpanded);

    /**
     * mChildData view holder
     *
     * @param parent
     * @param viewType {@link android.widget.BaseExpandableListAdapter#getChildType(int, int)}
     * @return
     */
    @NonNull
    protected abstract CVH onCreateChildViewHolder(ViewGroup parent, int viewType);

    /**
     * 更新child holder中view的数据
     *
     * @param holder
     * @param groupPosition
     * @param childPosition
     * @param isLastChild
     */
    protected abstract void onBindChildViewHolder(CVH holder, int groupPosition, int childPosition, boolean isLastChild);

    public List<GroupDataType> getGroupData() {
        return mGroupData;
    }

    public HashMap<GroupDataType, List<ChildDataType>> getChildData() {
        return mChildData;
    }

    public static class GroupViewHolder {
        final View groupItemView;

        public GroupViewHolder(View groupItemView) {
            if (groupItemView == null) {
                throw new IllegalArgumentException("itemView may not be null");
            }
            this.groupItemView = groupItemView;
            this.groupItemView.setTag(this);
        }
    }

    public static class ChildViewHolder {
        final View childItemView;

        public ChildViewHolder(View childItemView) {
            if (childItemView == null) {
                throw new IllegalArgumentException("itemView may not be null");
            }
            this.childItemView = childItemView;
            this.childItemView.setTag(this);
        }
    }

}
